/* LoadStoreTypes.h
 * 
 *  Author          : Alexander J. Yee
 *  Date Created    : 11/14/2015
 *  Last Modified   : 06/27/2024
 * 
 *      All enums here must be consecutive in value as they will be used
 * by "TemplateDispatch.h".
 * 
 */

#pragma once
#ifndef ymp_ArchSpecific_LoadStoreTypes_H
#define ymp_ArchSpecific_LoadStoreTypes_H
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//  Dependencies
#include <string>
#include "PublicLibs/CompilerSettings.h"
#include "PublicLibs/SystemLibs/ProcessorCapability/ProcessorCapability.h"
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//  Load Types
#if (defined YMP_Arch_2007_x64_Penryn)
#define ymp_LoadType_has_NON_TEMPORAL
#endif
#if 0   //  (defined YMP_Arch_2023_x64_CLDEMOTE)
#define ymp_LoadType_has_LOAD_AND_EVICT
#endif
////////////////////////////////////////////////////////////////////////////////
//  Store Types
#if (defined YMP_Arch_2001_x86_SSE2)
#define ymp_StoreType_has_NON_TEMPORAL
#endif
#if (defined YMP_Arch_2023_x64_CLDEMOTE)
#define ymp_StoreType_has_EVICT_TO_SHARED
#endif
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
namespace ymp{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
enum class LoadType{
    NORMAL,

#ifdef ymp_LoadType_has_NON_TEMPORAL
    NON_TEMPORAL,
#endif
#ifdef ymp_LoadType_has_LOAD_AND_EVICT
    LOAD_AND_EVICT,     //  NT-load + cldemote.
#endif
//    LOAD_AND_DESTROY,   //  A trim operation. Mark data as no longer needed.

    //  This must be the last member so that the count is correct.
    TOTAL_VALUES,

    //  Placeholders. Alias them to NORMAL so that references will compile.
#ifndef ymp_LoadType_has_NON_TEMPORAL
    NON_TEMPORAL    =   NORMAL,
#endif
#ifndef ymp_LoadType_has_LOAD_AND_EVICT
    LOAD_AND_EVICT  =   NORMAL,
#endif
};
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
enum class StoreType{
    NORMAL,

#ifdef ymp_StoreType_has_NON_TEMPORAL
    NON_TEMPORAL,
#endif
#ifdef ymp_StoreType_has_EVICT_TO_SHARED
    EVICT_TO_SHARED,    //  Store + cldemote. Evict to shared cache.
#endif

    //  This must be the last member so that the count is correct.
    TOTAL_VALUES,

    //  Placeholders. Alias them to NORMAL so that references will compile.
#ifndef ymp_StoreType_has_NON_TEMPORAL
    NON_TEMPORAL    =   NORMAL,
#endif
#ifndef ymp_StoreType_has_EVICT_TO_SHARED
    EVICT_TO_SHARED =   NORMAL,
#endif
};
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
enum class LoadPrefetch{
    NONE,

#ifdef YMP_Arch_2001_x86_SSE2
    PREFETCH_NTA,
    PREFETCH_T0,
    PREFETCH_T1,
    PREFETCH_T2,
#endif

    //  This must be the last member so that the count is correct.
    TOTAL_VALUES,

    //  Placeholders. Alias them to NONE so that references will compile.
#ifndef YMP_Arch_2001_x86_SSE2
    PREFETCH_NTA    =   NONE,
    PREFETCH_T0     =   NONE,
    PREFETCH_T1     =   NONE,
    PREFETCH_T2     =   NONE,
#endif
};
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
const char* to_string(LoadType type);
LoadType parse_LoadType(const std::string& str);
////////////////////////////////////////////////////////////////////////////////
const char* to_string(StoreType type);
StoreType parse_StoreType(const std::string& str);
////////////////////////////////////////////////////////////////////////////////
const char* to_string(LoadPrefetch type);
LoadPrefetch parse_LoadPrefetch(const std::string& str);
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
}
#endif
